package com.orhon.smartcampus.modules.base.fetcher;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.orhon.smartcampus.auth.JwtUtils;
import com.orhon.smartcampus.modules.base.dao.GradesDao;
import com.orhon.smartcampus.modules.base.dao.SchoolsDao;
import com.orhon.smartcampus.modules.base.dao.SubjectsDao;
import com.orhon.smartcampus.modules.base.entity.Grades;
import com.orhon.smartcampus.modules.base.entity.Schools;
import com.orhon.smartcampus.modules.base.entity.Subjects;
import com.orhon.smartcampus.modules.base.gqlModel.GQLGrades;
import com.orhon.smartcampus.modules.base.gqlModel.GQLSchool;
import com.orhon.smartcampus.modules.base.gqlModel.GQLSubject;
import com.orhon.smartcampus.modules.base.mm.GradeMapper;
import com.orhon.smartcampus.modules.base.mm.SchoolMapper;
import com.orhon.smartcampus.modules.base.mm.SubjectMapper;
import com.orhon.smartcampus.modules.systemctl.dao.OrgDutiesDao;
import com.orhon.smartcampus.modules.systemctl.entity.OrgDuties;
import com.orhon.smartcampus.modules.systemctl.entity.Schoolsettings;
import com.orhon.smartcampus.modules.systemctl.gqlModel.GQLDuty;
import com.orhon.smartcampus.modules.systemctl.mm.DutiesMapper;
import com.orhon.smartcampus.modules.user.dao.TokenService;
import com.orhon.smartcampus.utils.R;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import lombok.extern.slf4j.Slf4j;

/**
 * *学校基础数据
 * @author ebusu
 *
 */
@Component
@Slf4j(topic = "schoolInfoFetcher")
public class SchoolInfoFetcher implements DataFetcher<Object>{
	
	@Autowired
	private TokenService tokenService;
	
	@Autowired
	private SchoolsDao schoolsDao;
	
	@Autowired
	private SubjectsDao subjectsDao;
	
	@Autowired
	private GradesDao gradesDao;
	
	@Autowired
	private OrgDutiesDao orgDutiesDao;

	@Override
	@Transactional
	public Object get(DataFetchingEnvironment environment) throws Exception {
		
		String token = this.tokenService.getSystemToken();
		
		if ( StringUtils.isEmpty(token)) {
			return R.error("请先登录.");
		}
		
		Long currentSchoolId;
		
		try {
			currentSchoolId = JwtUtils.getSchoolId(this.tokenService.getSystemToken());
		} catch ( Throwable e ) {
			log.error(e.getMessage());
			throw new RuntimeException(e.getMessage());
		}
		
		String nativeSql = "SELECT bs.id, bs.school_name , bs.introduction, bs.address, bs.school_number, bs.school_slug,"
				+ " (SELECT COUNT(*) FROM systemctl_modules_school_relations WHERE school_id = bs.id) AS modulesCount,"
				+ " (SELECT COUNT(*) FROM user_users WHERE school_id = bs.id AND deleted_at IS NULL) AS userCount"
				+ " FROM base_schools bs "
				+ " where bs.id = " + currentSchoolId;
		
		@SuppressWarnings("unchecked")
		List<Object[]> schoolInfoList = this.schoolsDao.getTemplate().getSessionFactory().getCurrentSession()
				.createSQLQuery(nativeSql).list();
		
		if ( CollectionUtils.isEmpty(schoolInfoList) || schoolInfoList.size() != 1 ) {
			throw new RuntimeException("school info is error.");
		}
		
		Object[] schoolInfo = schoolInfoList.get(0);
		
		Schools schools = new Schools();
		
		schools.setId( Long.valueOf((Integer)schoolInfo[0]) );
		schools.setSchool_name( (String)schoolInfo[1] );
		if ( schoolInfo[2] != null ) {
			schools.setIntroduction((String)schoolInfo[2]);
		}
		if ( schoolInfo[3] != null ) {
			schools.setAddress((String)schoolInfo[3]);
		}
		if ( schoolInfo[4] != null ) {
			schools.setSchool_number(((Integer)schoolInfo[4]).toString());
		}
		if ( schoolInfo[5] != null ) {
			schools.setSchool_slug((String)schoolInfo[5]);
		}
		
		GQLSchool gqlSchool = SchoolMapper.MAPPER.toSchool(schools);
		gqlSchool.setModulesCount( ((BigInteger)schoolInfo[6]).intValue() );
		gqlSchool.setUserCount(((BigInteger)schoolInfo[7]).intValue());
		
		List<Schoolsettings> schoolSettings = this.schoolsDao.findById(currentSchoolId).getSettings();
		
		log.info("schoolSetting {}", schoolSettings);
		
		R r = R.ok();
		r.put("data", gqlSchool);
		
		if ( !CollectionUtils.isEmpty(schoolSettings) && schoolSettings.size() == 1) {
			
			Schoolsettings schoolsettings = schoolSettings.get(0);
			
			String subjectJsonArray = schoolsettings.getSubjects();
			
			if ( !StringUtils.isEmpty(subjectJsonArray)) {
				String subjectIds = subjectJsonArray.substring(1, subjectJsonArray.length() - 1);
				
				if ( !StringUtils.isEmpty(subjectIds)) {
					String[] subjectArray = subjectIds.split(",");
					List<GQLSubject> gqlSubjectList = new ArrayList<>(subjectArray.length);
					for ( int i = 0 ; i < subjectArray.length ; i ++ ) {
						Subjects subjects = this.subjectsDao.findById(Long.valueOf(subjectArray[i].trim()));
						GQLSubject gqlSubject = SubjectMapper.MAPPER.toSubject(subjects);
						gqlSubjectList.add(gqlSubject);
					}
					r.put("subjectData", gqlSubjectList);
					
				}
			}
			
			String gradeJsonArray = schoolsettings.getGrades();
			
			if ( !StringUtils.isEmpty(gradeJsonArray)) {
				String gradeIds = gradeJsonArray.substring(1, gradeJsonArray.length() - 1);
				
				if ( !StringUtils.isEmpty(gradeIds)) {
					String[] gradeArray = gradeIds.split(",");
					List<GQLGrades> gqlGradeList = new ArrayList<>(gradeArray.length);
					for ( int i = 0 ; i < gradeArray.length ; i ++ ) {
						Grades grades = this.gradesDao.findById(Long.valueOf(gradeArray[i].trim()));
						GQLGrades gqlGrades = GradeMapper.MAPPER.toGrade(grades);
						gqlGradeList.add(gqlGrades);
					}
					r.put("gradeData", gqlGradeList);
					
				}
			}
			
			String dutiesJsonArray = schoolsettings.getDuties();
			
			if ( !StringUtils.isEmpty(dutiesJsonArray)) {
				String dutiesIds = dutiesJsonArray.substring(1, dutiesJsonArray.length() - 1);
				
				if ( !StringUtils.isEmpty(dutiesIds)) {
					String[] dutiesArray = dutiesIds.split(",");
					List<GQLDuty> gqlDutyList = new ArrayList<>(dutiesArray.length);
					for ( int i = 0 ; i < dutiesArray.length ; i ++ ) {
						// OrgDuties orgDuties = this.orgDutiesDao.findById(Long.valueOf(dutiesArray[i].trim()));
						String dutySql = "select id, duties_name from systemctl_org_duties where id = " + dutiesArray[i].trim();
						List<Object[]> dutiesData = this.orgDutiesDao.getTemplate().getSessionFactory().getCurrentSession().createSQLQuery(dutySql).list();
						if ( dutiesData != null && dutiesData.size() == 1) {
							OrgDuties orgDuties = new OrgDuties();
							orgDuties.setDutiesName((String)dutiesData.get(0)[1]);
							GQLDuty gqlDuty = DutiesMapper.MAPPER.toOrgDuties(orgDuties);
							gqlDutyList.add(gqlDuty);
						}
					}
					r.put("dutyData", gqlDutyList);
					
				}
			}
			
		} else {
			throw new RuntimeException("the school setting data is error. school_id = " + currentSchoolId);
		}
		
		return r;
	}
}

